package com.example.internetplus.utils;

import cn.hutool.db.handler.StringHandler;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author luft-mensch
 */
@Data
@Component
public class RedisUtil {

    /**
     * 如果使用 @Autowired 注解完成自动装配 那么
     * RedisTemplate要么不指定泛型,要么泛型 为<Stirng,String> 或者<Object,Object>
     * 如果你使用其他类型的 比如RedisTemplate<String,Object>
     * 那么请使用 @Resource 注解
     * */
    @Resource(name = "stringRedisTemplate")
    private RedisTemplate<String,String> stringredisTemplate;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 缓存value
     *
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean cacheValue(String key, Object value, long time) {
        try {
            String valueStr = JSONUtil.toJsonStr(value);
            ValueOperations<String, String> valueOperations = stringredisTemplate.opsForValue();
            valueOperations.set(key, valueStr);
            if (time > 0) {
                // 如果有设置超时时间的话
                stringredisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Throwable e) {
            logger.error("缓存[" + key + "]失败, value[" + value + "] " + e.getMessage());
        }
        return false;
    }

    /**
     * 缓存value，没有设置超时时间
     *
     * @param key
     * @param value
     * @return
     */
    public boolean cacheValue(String key, Object value) {
        return cacheValue(key, value, -1);
    }

    /**
     * 判断缓存是否存在
     *
     * @param key
     * @return
     */
    public boolean containsKey(String key) {
        try {
            return stringredisTemplate.hasKey(key);
        } catch (Throwable e) {
            logger.error("判断缓存是否存在时失败key[" + key + "]", "err[" + e.getMessage() + "]");
        }
        return false;
    }

    /**
     * 根据key，获取缓存
     *
     * @param key
     * @return
     */
    public Object getValue(String key) {
        try {
            ValueOperations<String, String> valueOperations = stringredisTemplate.opsForValue();
            return valueOperations.get(key);
        } catch (Throwable e) {
            logger.error("获取缓存时失败key[" + key + "]", "err[" + e.getMessage() + "]");
        }
        return null;
    }

    /**
     * 添加set集合
     * @param key
     * @param values
     * @return
     */
    public Long addSet(String key, List values){
        try {
            for (Object value : values){
                String json = JSONUtil.toJsonStr(value);
                stringredisTemplate.opsForSet().add(key,json);
            }
        }catch (Throwable e){
            logger.error("添加集合缓存时报错" + key + "error" + e.getMessage());
        }
        return null;
    }

    /**
     * 获取集合元素
     * @param key
     * @return
     */
    public <T>List<T> getSet(String key, Class<T> clazz){
        try {
            Set<String> jsons = stringredisTemplate.opsForSet().members(key);
            ArrayList<T> datas = new ArrayList<>(jsons.size());
            for (String object : jsons){
                T data = JSONUtil.parseObj(object).toBean(clazz);
                datas.add(data);
            }
            return datas;
        }catch (Throwable e){
            logger.error("获取set集合时报错，key为" + key + "   error  " + e.getMessage());
        }
        return null;
    }
    /**
     * 移除缓存
     *
     * @param key
     * @return
     */
    public boolean removeValue(String key) {
        try {
            stringredisTemplate.delete(key);
            return true;
        } catch (Throwable e) {
            logger.error("移除缓存时失败key[" + key + "]", "err[" + e.getMessage() + "]");
        }
        return false;
    }

    /**
     * 根据前缀移除所有以传入前缀开头的key-value
     *
     * @param pattern
     * @return
     */
    public boolean removeKeys(String pattern) {
        try {
            Set<String> keySet = stringredisTemplate.keys(pattern + "*");
            stringredisTemplate.delete(keySet);
            return true;
        } catch (Throwable e) {
            logger.error("移除key[" + pattern + "]前缀的缓存时失败", "err[" + e.getMessage() + "]");
        }
        return false;
    }
    public boolean addList(String key,String message){
        stringredisTemplate.boundListOps(key).leftPush(message);
        return true;
    }
}
